package flexibilityDesign;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import support.ExcelOperator;
import util.Lang;
import util.MathUtil;

public class Support {

	public static final double BIG_NUM = 1000000.0;
	public static final double DEMAND_UP = 1000.0;// 3 times of demand mean

	/**
	 * @param count
	 *            instance number
	 * @param n
	 *            resource number
	 * **/
	public static double[][] readDemands(int count, int n) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\demand_" + count + "_" + n + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		double[][] demands = eo.read(path, "demand", count, n);
		return demands;
	}

	public static Map<Integer, List<Double[]>> readDemands_clustered(int count, int n) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\demand_" + count + "_" + n + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		return eo.read_clustered(path, "demand");
	}

	/**
	 * @param count
	 *            instance number
	 * @param n
	 *            resource number
	 * **/
	public static void generateDemands_normal(int count, int n, double mean, double variance, double low, double up) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\demand_" + count + "_" + n + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		if (!eo.exist(path)) {
			double[][] demands = MathUtil.normal(count, n, mean, variance, low, up);
			eo.write(path, "demand", demands, null);
		}
	}

	/**
	 * @param count
	 *            instance number
	 * @param n
	 *            resource number
	 * **/
	public static void generateDemands_normal(int count, int n, double mean, double variance, double low, double up,
			int index) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\demand_" + count + "_" + n + "_" + index
				+ ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		if (!eo.exist(path)) {
			double[][] demands = MathUtil.normal(count, n, mean, variance, low, up);
			eo.write(path, "demand", demands, null);
		}
	}

	/**
	 * @param count
	 *            instance number
	 * @param n
	 *            resource number
	 * **/
	public static double[][] readDemands(int count, int n, int index) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\demand_" + count + "_" + n + "_" + index
				+ ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		double[][] demands = eo.read(path, "demand", count, n);
		return demands;
	}

	/**
	 * @param n
	 *            demand
	 * @param m
	 *            resource
	 * **/
	public static double[][] readLinkCost(int n, int m) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\cost_" + n + "_" + m + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		double[][] cost = eo.read(path, "cost");
		return cost;
	}

	/**
	 * @param n
	 *            demand
	 * @param m
	 *            resource
	 * **/
	public static void generateLinkCost(int n, int m, double low, double up) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\cost_" + n + "_" + m + ".xlsx";
		ExcelOperator oe = new ExcelOperator();
		if (!oe.exist(path)) {
			double[][] cost = MathUtil.uniform(n, m, low, up);
			oe.write(path, "cost", cost, null);
		}
	}

	/**
	 * @param n
	 *            demand
	 * @param m
	 *            resource
	 * **/
	public static double[][] readProfitMargin(int n, int m) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\profit_" + n + "_" + m + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		double[][] cost = eo.read(path, "profit");
		return cost;
	}

	/**
	 * Uniform distribution.
	 * 
	 * @param n
	 *            demand
	 * @param m
	 *            resource
	 * @param lcpm
	 *            c_ij/pi_ij
	 * **/
	public static void generateProfitMargin(int n, int m, double low, double up, double lcpm) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\profit_" + n + "_" + m + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		if (!eo.exist(path)) {
			low = BigDecimal.valueOf(low).divide(BigDecimal.valueOf(lcpm), 5, BigDecimal.ROUND_HALF_EVEN).doubleValue();
			up = BigDecimal.valueOf(up).divide(BigDecimal.valueOf(lcpm), 5, BigDecimal.ROUND_HALF_EVEN).doubleValue();
			double[][] profit = MathUtil.uniform(n, m, low, up);
			eo.write(path, "profit", profit, null);
		}
	}

	/**
	 * @param m
	 *            plant num
	 * **/
	public static double[] readCapacityCost(int m) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\cap_cost_" + m + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		double[] cost = eo.readSingle(path, "cost");
		return cost;
	}

	/**
	 * It is supposed to be half of margin profit
	 * 
	 * @param m
	 *            plant num
	 * **/
	public static void generateCapacityCost(int m, double low, double up, double lcpm) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\cap_cost_" + m + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		if (!eo.exist(path)) {
			low = BigDecimal.valueOf(low).divide(BigDecimal.valueOf(lcpm), 5, BigDecimal.ROUND_HALF_EVEN).doubleValue();
			up = BigDecimal.valueOf(up).divide(BigDecimal.valueOf(lcpm), 5, BigDecimal.ROUND_HALF_EVEN).doubleValue();
			double[] ccost = MathUtil.uniform(m, low, up);
			eo.write(path, "cost", ccost);
		}
	}

	/**
	 * @param n
	 *            demand
	 * @param m
	 *            resource
	 * **/
	public static void generateCapacities(int n, int m) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\capacity_" + n + "_" + m + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		if (!eo.exist(path)) {
			BigDecimal cb = BigDecimal.valueOf(n * 100).divide(BigDecimal.valueOf(m), 5, BigDecimal.ROUND_HALF_EVEN);
			double ub = cb.multiply(BigDecimal.valueOf(1.3)).doubleValue();
			double lb = cb.multiply(BigDecimal.valueOf(0.7)).doubleValue();
			double[] capacities = MathUtil.uniform(m, lb, ub);
			eo.write(path, "capacity", capacities);
		}
	}

	public static double[] readCapacities(int n, int m) {
		String path = Lang.projectRoot() + "\\data\\flexibilityDesign\\capacity_" + n + "_" + m + ".xlsx";
		ExcelOperator eo = new ExcelOperator();
		double[] capacity = eo.readSingle(path, "capacity");
		return capacity;
	}

}
